#pragma once
#include <iostream>
#include<jsoncpp/json/json.h>

//#define MySelf 1

const std::string blank_sep = " ";   //用于分割 x op y
const std::string protocol_sep = "\n";  //用于分割 "len\n"x op y\n

// "len"\n"x op y"\n  或者 "len"\n"result exitcode"\n ,  len表示 "x op y" 或者 "result exitcode" 的长度
std::string Encode(std::string &in)
{
    std::string s = std::to_string(in.size());
    s += protocol_sep;
    s += in;
    s += protocol_sep;

    return s;
}

bool Decode(std::string &package, std::string *out) //"len"\n"x op y"\n
{
    size_t left_line = package.find(protocol_sep);
    if (left_line == std::string::npos)
        return false;

    std::string len_str = package.substr(0, left_line);
    size_t len = std::stoi(len_str);
    size_t total_size = len_str.size() + len + 2; // 一个有效数据的大小
    if (package.size() < total_size)              // package的大小 一定是大于或等于total_size 的大小的
        return false;

    std::string content = package.substr(left_line + 1, left_line + len);  // x op y
    *out = content;
    package.erase(0,total_size); // 移除已经确定的报文
    return true;
}
class Request
{
public:
    Request(int x, int y, char op)
        : x_(x), y_(y), op_(op)
    {}

    Request()
    {}

    bool Serialize(std::string *out) // x op y , 将对象成员构造成 字符串
    {
#ifdef MySelf        
        std::string s = std::to_string(x_);
        s += blank_sep;
        s += op_;
        s += blank_sep;
        s += std::to_string(y_);

        *out = s;
#else
        Json::Value root;
        root["x"] = x_;
        root["y"] = y_;
        root["op"] = op_;
        Json::StyledWriter w;
        *out = w.write(root);

#endif
        return true;
    }

    bool Deserialize(std::string &in) // x op y  , 反序列将 字符串 构造成对象
    {
#ifdef MySelf        
        // 找到 x
        size_t left_blank = in.find(blank_sep);
        if (left_blank == std::string::npos)
            return false;
        std::string x = in.substr(0, left_blank);

        // 找到y
        size_t right_blank = in.rfind(blank_sep);
        if (right_blank == std::string::npos)
            return false;
        std::string y = in.substr(right_blank + 1);

        if (left_blank + 2 != right_blank) // 左空格和右空格差两个字符
            return false;

        op_ = in[left_blank + 1];
        x_ = std::stoi(x);
        y_ = std::stoi(y);
#else
        Json::Value root;
        Json::Reader r;
        r.parse(in,root);
        x_ = root["x"].asInt();
        y_ = root["y"].asInt();
        op_ = root["op"].asInt();

#endif
        return true;
    }

    void Print()
    {
        std::cout << x_ << " " << op_ << " " << y_ << "=?? "<<std::endl;
    }
public:
    int x_;
    int y_;
    char op_; // + - * /
};

class Response
{
public:
    Response(int result, int exitcode)
        : result_(result), exitcode_(exitcode)
    {
    }

    Response()
    {}
    bool Serialize(std::string *out) // result exitcode , 将对象成员构造成 字符串
    {
#ifdef MySelf                
        std::string s = std::to_string(result_);
        s += blank_sep;
        s += std::to_string(exitcode_);

        *out = s;
#else
        Json::Value root;
        root["result"] = result_;
        root["exit"] = exitcode_;
        Json::StyledWriter w;
        *out = w.write(root);

#endif
        return true;
    }

    bool Deserialize(std::string &in) // result exitcode , 反序列将 字符串 构造成对象
    {
#ifdef MySelf                
        // 找到 result
        size_t blank = in.find(blank_sep);
        if (blank == std::string::npos)
            return false;
        std::string result = in.substr(0, blank);

        // 找到 exitcode
        std::string exitcode = in.substr(blank + 1);

        result_ = std::stoi(result);
        exitcode_ = std::stoi(exitcode);
#else
        Json::Value root;
        Json::Reader r;
        r.parse(in,root);
        result_ = root["result"].asInt();
        exitcode_ = root["exit"].asInt();
        
#endif
        return true;
    }

public:
    int result_;
    int exitcode_;
};